package cn.t.modules.scheduler.core.schedule.repository.dao;

import cn.t.modules.scheduler.common.enums.ScheduleStatus;
import cn.t.modules.scheduler.common.utils.TimeUtil;
import cn.t.modules.scheduler.core.schedule.repository.mapper.ScheduleMapper;
import cn.t.modules.scheduler.core.schedule.repository.po.SchedulePo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;

/**
 * @author 陶敏麒
 * @date 2024/3/6 15:52
 */
@Repository
public class ScheduleDao extends ServiceImpl<ScheduleMapper, SchedulePo> {

    public List<SchedulePo> queryAcceptedScheduleList(int limit) {
        return this.lambdaQuery()
                .eq(SchedulePo::getStatus, ScheduleStatus.ACCEPTED)
                // 执行时间小于当前时间+80秒的(考虑到延迟,所以冗余的多一些)
                .lt(SchedulePo::getExecTimeTs, System.currentTimeMillis() + 80000)
                .last("limit " + limit)
                .list();
    }

    public void updateStatus(long id, ScheduleStatus scheduleStatus, String desc, int version) {
        var lambda = this.lambdaUpdate()
                .set(SchedulePo::getStatus, scheduleStatus)
                .set(SchedulePo::getUpdateTime, TimeUtil.currentTime())
                .set(SchedulePo::getVersion, version + 1)
                .eq(SchedulePo::getId, id);
        if (StringUtils.hasText(desc)) {
            lambda.set(SchedulePo::getDesc, desc);
        }
        lambda.update();
    }

    public void updateStatusBatch(Set<Long> ids, ScheduleStatus scheduleStatus, String desc) {
        var lambda = this.lambdaUpdate()
                .set(SchedulePo::getStatus, scheduleStatus)
                .set(SchedulePo::getUpdateTime, TimeUtil.currentTime())
                .in(SchedulePo::getId, ids);
        if (StringUtils.hasText(desc)) {
            lambda.set(SchedulePo::getDesc, desc);
        }
        lambda.update();
    }

    /**
     * 指定的数据是否变更过
     */
    public boolean hasChanged(long id, int version, ScheduleStatus scheduleStatus) {
        return !this.lambdaQuery()
                .eq(SchedulePo::getId, id)
                .eq(SchedulePo::getVersion, version)
                .eq(SchedulePo::getStatus, scheduleStatus)
                .exists();
    }

    public void clearScheduleHistory(long clearTimeTs) {
        this.lambdaUpdate().lt(SchedulePo::getExecTimeTs, clearTimeTs)
                .ne(SchedulePo::getStatus, ScheduleStatus.ACCEPTED)
                .remove();
    }
}
